/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cn.icanci.logparser.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.icanci.logparser.entity.SystemBaseLogDetailDO;
import cn.icanci.logparser.form.ViewVO;
import cn.icanci.logparser.mapper.SystemLogBaseMapper;
import cn.icanci.logparser.service.SystemBaseLogService;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

/**
* @author icanci
* @date  Created in 2021/04/11 15:45
* @version 1.0
*/
@Service
public class SystemBaseLogServiceImpl implements SystemBaseLogService {
    @Resource
    private SystemLogBaseMapper systemLogBaseMapper;

    /**
     * 保存一条日志数据
     * @param systemBaseLogDetailDO 日志对象
     */
    @Override
    public void insertOneRow(SystemBaseLogDetailDO systemBaseLogDetailDO) {
        systemLogBaseMapper.insertOneRow(systemBaseLogDetailDO);
    }

    /**
     * 查询时间范围的数据
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 返回查询的数据集合
     */
    @Override
    public List<ViewVO> queryList(Date startTime, Date endTime, String module) {
        List<SystemBaseLogDetailDO> systemBaseLogDetailDOS = systemLogBaseMapper.queryListByTime(startTime, endTime, module);
        if (CollectionUtil.isEmpty(systemBaseLogDetailDOS)) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 按照天进行分组
        Map<String, List<SystemBaseLogDetailDO>> map = systemBaseLogDetailDOS.stream().collect(Collectors.groupingBy(o -> simpleDateFormat.format(o.getCreateTime())));
        List<ViewVO> viewVOS = Lists.newArrayList();
        List<String> hasDate = Lists.newArrayList();
        for (Map.Entry<String, List<SystemBaseLogDetailDO>> entry : map.entrySet()) {
            String key = entry.getKey();
            List<SystemBaseLogDetailDO> value = entry.getValue();
            ViewVO viewVO = new ViewVO();
            viewVO.setDate(key);
            viewVO.setVisitCount(CollectionUtil.isEmpty(value) ? 0 : value.size());
            viewVOS.add(viewVO);
            hasDate.add(key);
        }
        try {
            List<String> timeRate = getTimeRate(startTime, endTime);
            for (String s : timeRate) {
                if (!hasDate.contains(s)) {
                    ViewVO vo = new ViewVO();
                    vo.setDate(s);
                    vo.setVisitCount(0);
                    viewVOS.add(vo);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        viewVOS.sort((o1, o2) -> {
            return o1.getDate().compareTo(o2.getDate());
        });
        return viewVOS;
    }
    //    ================================ 非接口方法 ================================

    /**
     * 获取范围之内的所有时间
     * @param begin 开始时间
     * @param end 结束时间
     * @return 返回时间节点的结合
     * @throws Exception 解析失败异常
     */
    private static List<String> getTimeRate(Date begin, Date end) throws Exception {
        SimpleDateFormat sdfRes = new SimpleDateFormat("yyyy-MM-dd");
        List<Date> lDate = new ArrayList();
        lDate.add(begin);
        Calendar calBegin = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calBegin.setTime(begin);
        Calendar calEnd = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        calEnd.setTime(end);
        // 测试此日期是否在指定日期之后
        while (end.after(calBegin.getTime())) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            calBegin.add(Calendar.DAY_OF_MONTH, 1);
            lDate.add(calBegin.getTime());
        }
        List<String> timeStringList = new ArrayList<>();
        for (Date datePes : lDate) {
            String format = sdfRes.format(datePes);
            timeStringList.add(format);
        }
        return timeStringList;
    }
}
